package main

import (
	"log"
	"gateway-api/tools"

	amqp "github.com/rabbitmq/amqp091-go"
)

/*
 +----------------------------------------------------------------------
 + Title        : deadConsumer
 + Author       : huwl
 + Version      : 2.0.0
 + Initial-Time : 2020-11-23
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 死信消费者
 +----------------------------------------------------------------------
*/

// 运行程序命令: go run .\consoles\rabbitMQConsumer\tridentConsumer\deadConsumer\main.go

/**
 * 死信队列消费者
 *
 * @param string queueName ----------------------------------必传,队列名称
 * @param string exchangeName -------------------------------必传,交换机名称
 * @param string consumerName -------------------------------必传,消费者名称
 * @param string exchangeBindQueueRoutingKey ----------------必传,绑定队列路由
 * @author huwl
 */
func DeadConsumer(queueName, exchangeName, consumerName, exchangeBindQueueRoutingKey string) {
	log.Println("------------- dead " + consumerName + " start -------------")

	// 创建RabbitMQ
	rm, err := tools.NewRabbitMQ()
	if err != nil {
		log.Fatalf("Failed to create RabbitMQ: %v", err)
	}
	// 申明死信交换机
	err = rm.ExchangeDeclare(tools.ExchangeDeclareParams{
		Name:    exchangeName,
		Kind:    "topic",
		Durable: true,
	})
	if err != nil {
		log.Fatalf("Failed to ExchangeDeclare: %v", err)
	}

	// 申明死信队列
	err = rm.QueueDeclare([]tools.QueueDeclareParams{
		tools.QueueDeclareParams{
			Queue:   queueName,
			Durable: true,
			AmqpTable: amqp.Table{
				"x-queue-mode": "lazy",
			},
		},
	})
	if err != nil {
		log.Fatalf("Failed to QueueDeclare: %v", err)
	}

	// 绑定死信队列
	err = rm.ExchangeBindQueue(
		tools.QueueBindParam{
			QueueName:    queueName,
			RoutingKey:   exchangeBindQueueRoutingKey,
			ExchangeName: exchangeName,
		},
	)
	if err != nil {
		log.Fatalf("Failed to ExchangeBindQueue: %v", err)
	}

	// 在没有返回ack之前，最多只接收1个消息
	// 设置 prefetch count数值为1，这样只有当消费者消费完消息并返回ack确认后RabbitMQ才会给其分发消息，否则只会将消息分发给其他空闲状态的消费者
	err = rm.Ch.Qos(1, 0, false)
	if err != nil {
		log.Fatalf("Failed to Qos: %v", err)
	}

	// 消费消息
	rm.ConsumeMessage(tools.ConsumerMessageParam{
		Queue:    queueName,    // 队列名称
		Consumer: consumerName, // 消费者名称
		AutoAck:  false,        // true: 自动回复,false: 手动回复
	})
}
func main() {
	go DeadConsumer("trident-dead.queue", "trident-dead.exchange", "DeadConsumer-01", "trident-dead")
	go DeadConsumer("trident-dead.queue", "trident-dead.exchange", "DeadConsumer-02", "trident-dead")
	DeadConsumer("trident-dead.queue", "trident-dead.exchange", "DeadConsumer-03", "trident-dead")
}
